#include "IR-struct.h"

List function_list;
bool var_mark[20000];
BB * label_entry[20000];

static void deal_operand(Operand x, bool flag){
    uLL no=x.var.no;
    if(x.var.addr_status==-1) var_mark[no]=true;
    return;
}
#define DEAL(name,flag) deal_operand(name,flag)

operation * operation_build(int op,Operand x,Operand y,Operand z,uLL info){
    NEW_V(ret,operation,.op=op,.x=x,.y=y,.z=z,.info=info)
    switch (op){
        case OP_ASSIGN: case OP_READ:
            DEAL(x,1); DEAL(y,0); break;
        case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV:
            DEAL(x,1); DEAL(y,0); DEAL(z,0); break;
        case OP_IF:
            DEAL(x,0); DEAL(y,0); break;
        case OP_RET: case OP_WRITE: case OP_ARG:
            DEAL(x,0); break;
        case OP_DEC:case OP_CALL:
            DEAL(x,1); break;
        default:
            break;
    }
    return ret;
}

static void BB_insert(BB * self, operation * statemnt){
    if(statemnt->op==OP_LABEL) label_entry[statemnt->x.label]=self;
    LIST_INSERT(self->statement,statemnt);
    return;
}

void function_insert_statement(function * self,operation * statement){
    int op=statement->op;
    if(op==OP_LABEL||self->insert_status==0){
        NEW_V(bb,BB)
        if(self->BBlist.end) LIST_GET(self->BBlist.end,BB *)->nxt0=bb;
        LIST_INSERT(self->BBlist,bb);
        self->insert_status=1;
    }
    BB * last=LIST_GET(self->BBlist.end,BB*);
    BB_insert(last,statement);
    if(op==OP_GOTO||op==OP_IF||op==OP_RET) self->insert_status=0;
    return;
}
